from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
import time
from datetime import datetime, timedelta

from user_app.models import User
from user_app.utils import generate_access_token
from subjects_app.models import Subject
from content_app.models import Content
from .models import LearningProgress, LearningHistory

class LearningProgressTestCase(TestCase):
    def setUp(self):
        # 设置测试客户端
        self.client = APIClient()
        
        # 创建测试用户
        self.user = User.objects.create(
            phone='13800138001',
            password='hashed_password',
            nickname='TestUser'
        )
        
        # 创建测试学科
        self.subject = Subject.objects.create(
            name='测试学科',
            key='test_subject'
        )
        
        # 创建测试内容
        self.content = Content.objects.create(
            title='测试内容',
            subject=self.subject,
            file_path='/test/path/content.pdf'
        )
        
        # 生成访问令牌
        self.access_token = generate_access_token(self.user.id)
        
        # 设置请求头 - 有些实现可能需要去掉'Bearer '前缀
        # 直接使用token值作为Authorization头
        self.client.credentials(HTTP_AUTHORIZATION=self.access_token)
    
    def test_get_learning_progress_list(self):
        # 创建测试数据
        LearningProgress.objects.create(
            user=self.user,
            content_type='subject',
            content_id=self.subject.id,
            progress_percentage=50,
            is_completed=False,
            learning_time_seconds=300
        )
        
        LearningProgress.objects.create(
            user=self.user,
            content_type='content',
            content_id=self.content.id,
            progress_percentage=100,
            is_completed=True,
            learning_time_seconds=600
        )
        
        # 测试获取所有进度
        url = reverse('learning_progress')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data), 2)
        
        # 测试按内容类型过滤
        url = f'{reverse("learning_progress")}?content_type=subject'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0]['content_type'], 'subject')
    
    def test_create_or_update_learning_progress(self):
        # 测试创建新的进度记录
        url = reverse('learning_progress')
        data = {
            'content_type': 'subject',
            'content_id': self.subject.id,
            'progress_percentage': 75,
            'is_completed': False,
            'learning_time_seconds': 450
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['progress_percentage'], 75)
        
        # 测试更新已有的进度记录
        data = {
            'content_type': 'subject',
            'content_id': self.subject.id,
            'progress_percentage': 90,
            'is_completed': True
        }
        response = self.client.post(reverse('learning_progress'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['progress_percentage'], 90)
        self.assertTrue(response.data['is_completed'])
        
        # 测试缺少必要参数
        data = {
            'content_type': 'subject'
            # 缺少content_id
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
    
    def test_get_content_progress(self):
        # 创建测试数据
        progress = LearningProgress.objects.create(
            user=self.user,
            content_type='content',
            content_id=self.content.id,
            progress_percentage=80,
            is_completed=False,
            learning_time_seconds=500
        )
        
        # 测试获取特定内容的进度
        url = f'{reverse("content_progress")}?content_type=content&content_id={self.content.id}'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['progress_percentage'], 80)
        
        # 测试获取不存在的进度
        url = f'{reverse("content_progress")}?content_type=subject&content_id=999'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        
        # 测试缺少必要参数
        url = f'{reverse("content_progress")}?content_type=content'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
    
    def test_record_learning_history(self):
        # 准备测试数据
        now = datetime.now()
        start_time = now.isoformat()
        end_time = (now + timedelta(seconds=300)).isoformat()
        
        url = reverse('learning_history')
        data = {
            'content_type': 'content',
            'content_id': self.content.id,
            'start_time': start_time,
            'end_time': end_time
        }
        
        # 测试记录学习历史
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(LearningHistory.objects.count(), 1)
        self.assertEqual(response.data['duration_seconds'], 300)
        
        # 测试缺少必要参数
        data = {
            'content_type': 'content',
            'content_id': self.content.id
            # 缺少start_time和end_time
        }
        response = self.client.post(reverse('learning_history'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
    
    def test_get_learning_statistics(self):
        # 创建测试数据
        LearningProgress.objects.create(
            user=self.user,
            content_type='subject',
            content_id=self.subject.id,
            progress_percentage=50,
            is_completed=False,
            learning_time_seconds=300
        )
        
        LearningProgress.objects.create(
            user=self.user,
            content_type='content',
            content_id=self.content.id,
            progress_percentage=100,
            is_completed=True,
            learning_time_seconds=600
        )
        
        # 测试获取统计信息
        url = reverse('learning_statistics')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['total_learning_time_seconds'], 900)
        self.assertEqual(response.data['completed_items'], 1)
        self.assertEqual(response.data['total_items'], 2)
        self.assertEqual(response.data['progress_rate'], 50.0)
        
        # 测试按内容类型过滤统计
        url = f'{reverse("learning_statistics")}?content_type=subject'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['total_learning_time_seconds'], 300)
        self.assertEqual(response.data['completed_items'], 0)
        self.assertEqual(response.data['total_items'], 1)
        self.assertEqual(response.data['progress_rate'], 0.0)

    def test_unauthorized_access(self):
        # 移除认证信息
        self.client.credentials()
        
        # 测试未授权访问
        url = reverse('learning_progress')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        
        url = reverse('content_progress')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        
        url = reverse('learning_history')
        response = self.client.post(url, {}, format='json')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        
        url = reverse('learning_statistics')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

# Create your tests here.
